
require 'parser/Sym.rb'
# = Class SymFunction
# Inherits from class Sym, represents a function symbol
class SymFunction < Sym
    # Array containing the types of the parameters that the function represented receives
    attr_reader :param_types
    # Value returned by the function
    attr_reader :returned
    
  # Constructor of the class
  # === Parameters
  # * func -> function that wants to be created
    def initialize func
        @name = func.name.node.value
        @type = func.type.value
        @param_types = []
        for param in func.params
          #type of parameter
          @param_types.push(param.node.value)
        end
        @func = func
    end

    # Function to get the type for the signature specified by 'params'
    # === Parameters
    # * params -> Signature of the function
    # === Return value
    # Type of the return value of the function acording to the specified signature
    def type params
      if nil == params
        return @type
      end

      compare_types = []

      # Parameters are already checked, here we compare types
      for param in params
        compare_types.push param.type
      end

      # Types should be identical in the same order
      if compare_types != param_types
        raise InvalidCall.new("Las firmas aceptadas por la función #{@name} son: (#{param_types.join(', ')})" +
              " pero se encontró (#{compare_types.join(', ')})")
      end

      @type
    end

    # Executes de function contained in 'self'
    # === Parameters
    # * params -> True value of the parameters that the function will be evaluated with
    # * func_table -> Symbol table of the declared functions
    # === Return value
    # nil if executed with success or an error message
    def execute params, func_table
      msg = @func.run params, func_table
      if msg != nil
        return msg
      end
      @returned = @func.returned
      nil
    end
end
